manpages = {
  # Category 1.
  'git-add.txt' : 1,
  'git-am.txt' : 1,
  'git-annotate.txt' : 1,
  'git-apply.txt' : 1,
  'git-archimport.txt' : 1,
  'git-archive.txt' : 1,
  'git-backfill.txt' : 1,
  'git-bisect.txt' : 1,
  'git-blame.txt' : 1,
  'git-branch.txt' : 1,
  'git-bugreport.txt' : 1,
  'git-bundle.txt' : 1,
  'git-cat-file.txt' : 1,
  'git-check-attr.txt' : 1,
  'git-check-ignore.txt' : 1,
  'git-check-mailmap.txt' : 1,
  'git-checkout-index.txt' : 1,
  'git-checkout.txt' : 1,
  'git-check-ref-format.txt' : 1,
  'git-cherry-pick.txt' : 1,
  'git-cherry.txt' : 1,
  'git-citool.txt' : 1,
  'git-clean.txt' : 1,
  'git-clone.txt' : 1,
  'git-column.txt' : 1,
  'git-commit-graph.txt' : 1,
  'git-commit-tree.txt' : 1,
  'git-commit.txt' : 1,
  'git-config.txt' : 1,
  'git-count-objects.txt' : 1,
  'git-credential-cache--daemon.txt' : 1,
  'git-credential-cache.txt' : 1,
  'git-credential-store.txt' : 1,
  'git-credential.txt' : 1,
  'git-cvsexportcommit.txt' : 1,
  'git-cvsimport.txt' : 1,
  'git-cvsserver.txt' : 1,
  'git-daemon.txt' : 1,
  'git-describe.txt' : 1,
  'git-diagnose.txt' : 1,
  'git-diff-files.txt' : 1,
  'git-diff-index.txt' : 1,
  'git-difftool.txt' : 1,
  'git-diff-tree.txt' : 1,
  'git-diff.txt' : 1,
  'git-fast-export.txt' : 1,
  'git-fast-import.txt' : 1,
  'git-fetch-pack.txt' : 1,
  'git-fetch.txt' : 1,
  'git-filter-branch.txt' : 1,
  'git-fmt-merge-msg.txt' : 1,
  'git-for-each-ref.txt' : 1,
  'git-for-each-repo.txt' : 1,
  'git-format-patch.txt' : 1,
  'git-fsck-objects.txt' : 1,
  'git-fsck.txt' : 1,
  'git-fsmonitor--daemon.txt' : 1,
  'git-gc.txt' : 1,
  'git-get-tar-commit-id.txt' : 1,
  'git-grep.txt' : 1,
  'git-gui.txt' : 1,
  'git-hash-object.txt' : 1,
  'git-help.txt' : 1,
  'git-hook.txt' : 1,
  'git-http-backend.txt' : 1,
  'git-http-fetch.txt' : 1,
  'git-http-push.txt' : 1,
  'git-imap-send.txt' : 1,
  'git-index-pack.txt' : 1,
  'git-init-db.txt' : 1,
  'git-init.txt' : 1,
  'git-instaweb.txt' : 1,
  'git-interpret-trailers.txt' : 1,
  'git-log.txt' : 1,
  'git-ls-files.txt' : 1,
  'git-ls-remote.txt' : 1,
  'git-ls-tree.txt' : 1,
  'git-mailinfo.txt' : 1,
  'git-mailsplit.txt' : 1,
  'git-maintenance.txt' : 1,
  'git-merge-base.txt' : 1,
  'git-merge-file.txt' : 1,
  'git-merge-index.txt' : 1,
  'git-merge-one-file.txt' : 1,
  'git-mergetool--lib.txt' : 1,
  'git-mergetool.txt' : 1,
  'git-merge-tree.txt' : 1,
  'git-merge.txt' : 1,
  'git-mktag.txt' : 1,
  'git-mktree.txt' : 1,
  'git-multi-pack-index.txt' : 1,
  'git-mv.txt' : 1,
  'git-name-rev.txt' : 1,
  'git-notes.txt' : 1,
  'git-p4.txt' : 1,
  'git-pack-objects.txt' : 1,
  'git-pack-redundant.txt' : 1,
  'git-pack-refs.txt' : 1,
  'git-patch-id.txt' : 1,
  'git-prune-packed.txt' : 1,
  'git-prune.txt' : 1,
  'git-pull.txt' : 1,
  'git-push.txt' : 1,
  'git-quiltimport.txt' : 1,
  'git-range-diff.txt' : 1,
  'git-read-tree.txt' : 1,
  'git-rebase.txt' : 1,
  'git-receive-pack.txt' : 1,
  'git-reflog.txt' : 1,
  'git-refs.txt' : 1,
  'git-remote-ext.txt' : 1,
  'git-remote-fd.txt' : 1,
  'git-remote.txt' : 1,
  'git-repack.txt' : 1,
  'git-replace.txt' : 1,
  'git-replay.txt' : 1,
  'git-request-pull.txt' : 1,
  'git-rerere.txt' : 1,
  'git-reset.txt' : 1,
  'git-restore.txt' : 1,
  'git-revert.txt' : 1,
  'git-rev-list.txt' : 1,
  'git-rev-parse.txt' : 1,
  'git-rm.txt' : 1,
  'git-send-email.txt' : 1,
  'git-send-pack.txt' : 1,
  'git-shell.txt' : 1,
  'git-sh-i18n--envsubst.txt' : 1,
  'git-sh-i18n.txt' : 1,
  'git-shortlog.txt' : 1,
  'git-show-branch.txt' : 1,
  'git-show-index.txt' : 1,
  'git-show-ref.txt' : 1,
  'git-show.txt' : 1,
  'git-sh-setup.txt' : 1,
  'git-sparse-checkout.txt' : 1,
  'git-stage.txt' : 1,
  'git-stash.txt' : 1,
  'git-status.txt' : 1,
  'git-stripspace.txt' : 1,
  'git-submodule.txt' : 1,
  'git-survey.txt' : 1,
  'git-svn.txt' : 1,
  'git-switch.txt' : 1,
  'git-symbolic-ref.txt' : 1,
  'git-tag.txt' : 1,
  'git-unpack-file.txt' : 1,
  'git-unpack-objects.txt' : 1,
  'git-update-index.txt' : 1,
  'git-update-ref.txt' : 1,
  'git-update-server-info.txt' : 1,
  'git-upload-archive.txt' : 1,
  'git-upload-pack.txt' : 1,
  'git-var.txt' : 1,
  'git-verify-commit.txt' : 1,
  'git-verify-pack.txt' : 1,
  'git-verify-tag.txt' : 1,
  'git-version.txt' : 1,
  'git-web--browse.txt' : 1,
  'git-whatchanged.txt' : 1,
  'git-worktree.txt' : 1,
  'git-write-tree.txt' : 1,
  'git.txt' : 1,
  'gitk.txt' : 1,
  'gitweb.txt' : 1,
  'scalar.txt' : 1,

  # Category 5.
  'gitattributes.txt' : 5,
  'gitformat-bundle.txt' : 5,
  'gitformat-chunk.txt' : 5,
  'gitformat-commit-graph.txt' : 5,
  'gitformat-index.txt' : 5,
  'gitformat-pack.txt' : 5,
  'gitformat-signature.txt' : 5,
  'githooks.txt' : 5,
  'gitignore.txt' : 5,
  'gitmailmap.txt' : 5,
  'gitmodules.txt' : 5,
  'gitprotocol-capabilities.txt' : 5,
  'gitprotocol-common.txt' : 5,
  'gitprotocol-http.txt' : 5,
  'gitprotocol-pack.txt' : 5,
  'gitprotocol-v2.txt' : 5,
  'gitrepository-layout.txt' : 5,
  'gitweb.conf.txt' : 5,

  # Category 7.
  'gitcli.txt' : 7,
  'gitcore-tutorial.txt' : 7,
  'gitcredentials.txt' : 7,
  'gitcvs-migration.txt' : 7,
  'gitdiffcore.txt' : 7,
  'giteveryday.txt' : 7,
  'gitfaq.txt' : 7,
  'gitglossary.txt' : 7,
  'gitpacking.txt' : 7,
  'gitnamespaces.txt' : 7,
  'gitremote-helpers.txt' : 7,
  'gitrevisions.txt' : 7,
  'gitsubmodules.txt' : 7,
  'gittutorial-2.txt' : 7,
  'gittutorial.txt' : 7,
  'gitworkflows.txt' : 7,
}

docs_backend = get_option('docs_backend')
if docs_backend == 'auto'
  if find_program('asciidoc', required: false).found()
    docs_backend = 'asciidoc'
  elif find_program('asciidoctor', required: false).found()
    docs_backend = 'asciidoctor'
  else
    error('Neither asciidoc nor asciidoctor were found.')
  endif
endif

if docs_backend == 'asciidoc'
  asciidoc = find_program('asciidoc', required: true)
  asciidoc_html = 'xhtml11'
  asciidoc_docbook = 'docbook'
  xmlto_extra = [ ]

  asciidoc_conf = custom_target(
    command: [
      shell,
      meson.project_source_root() / 'GIT-VERSION-GEN',
      meson.project_source_root(),
      '@INPUT@',
      '@OUTPUT@',
    ],
    input: 'asciidoc.conf.in',
    output: 'asciidoc.conf',
    depends: [git_version_file],
    env: version_gen_environment,
  )

  asciidoc_common_options = [
    asciidoc,
    '--conf-file=' + asciidoc_conf.full_path(),
    '--attribute=build_dir=' + meson.current_build_dir(),
  ]

  documentation_deps = [
    asciidoc_conf,
  ]
elif docs_backend == 'asciidoctor'
  asciidoctor = find_program('asciidoctor', required: true)
  asciidoc_html = 'xhtml5'
  asciidoc_docbook = 'docbook5'
  xmlto_extra = [
    '--skip-validation',
    '-x', meson.current_source_dir() / 'manpage.xsl',
  ]

  asciidoctor_extensions = custom_target(
    command: [
      shell,
      meson.project_source_root() / 'GIT-VERSION-GEN',
      meson.project_source_root(),
      '@INPUT@',
      '@OUTPUT@',
    ],
    input: 'asciidoctor-extensions.rb.in',
    output: 'asciidoctor-extensions.rb',
    depends: [git_version_file],
    env: version_gen_environment,
  )

  asciidoc_common_options = [
    asciidoctor,
    '--attribute', 'compat-mode',
    '--attribute', 'tabsize=8',
    '--attribute', 'litdd=&#x2d;&#x2d;',
    '--attribute', 'docinfo=shared',
    '--attribute', 'build_dir=' + meson.current_build_dir(),
    '--load-path', meson.current_build_dir(),
    '--require', 'asciidoctor-extensions',
  ]

  documentation_deps = [
    asciidoctor_extensions,
  ]
endif

git = find_program('git', required: false)
xmlto = find_program('xmlto')

cmd_lists = [
  'cmds-ancillaryinterrogators.txt',
  'cmds-ancillarymanipulators.txt',
  'cmds-mainporcelain.txt',
  'cmds-plumbinginterrogators.txt',
  'cmds-plumbingmanipulators.txt',
  'cmds-synchingrepositories.txt',
  'cmds-synchelpers.txt',
  'cmds-guide.txt',
  'cmds-developerinterfaces.txt',
  'cmds-userinterfaces.txt',
  'cmds-purehelpers.txt',
  'cmds-foreignscminterface.txt',
]

documentation_deps += custom_target(
  command: [
    perl,
    '@INPUT@',
    meson.project_source_root(),
    meson.current_build_dir(),
  ] + cmd_lists,
  input: 'cmd-list.perl',
  output: cmd_lists
)

foreach mode : [ 'diff', 'merge' ]
  documentation_deps += custom_target(
    command: [
      shell,
      '@INPUT@',
      '..',
      mode,
      '@OUTPUT@'
    ],
    env: [
      'MERGE_TOOLS_DIR=' + meson.project_source_root() / 'mergetools',
    ],
    input: 'generate-mergetool-list.sh',
    output: 'mergetools-' + mode + '.txt',
  )
endforeach

foreach manpage, category : manpages
  if get_option('docs').contains('man')
    manpage_xml_target = custom_target(
      command: asciidoc_common_options + [
        '--backend=' + asciidoc_docbook,
        '--doctype=manpage',
        '--out-file=@OUTPUT@',
        '@INPUT@',
      ],
      depends: documentation_deps,
      input: manpage,
      output: fs.stem(manpage) + '.xml',
    )

    manpage_path = fs.stem(manpage) + '.' + category.to_string()
    manpage_target = custom_target(
      command: [
        xmlto,
        '-m', '@INPUT0@',
        '-m', '@INPUT1@',
        '--stringparam',
        'man.base.url.for.relative.links=' + get_option('prefix') / get_option('mandir'),
        'man',
        manpage_xml_target,
        '-o',
        meson.current_build_dir(),
      ] + xmlto_extra,
      input: [
        'manpage-normal.xsl',
        'manpage-bold-literal.xsl',
      ],
      output: manpage_path,
      install: true,
      install_dir: get_option('mandir') / 'man' + category.to_string(),
    )
  endif

  if get_option('docs').contains('html')
    custom_target(
      command: asciidoc_common_options + [
        '--backend=' + asciidoc_html,
        '--doctype=manpage',
        '--out-file=@OUTPUT@',
        '@INPUT@',
      ],
      depends: documentation_deps,
      input: manpage,
      output: fs.stem(manpage) + '.html',
      install: true,
      install_dir: get_option('datadir') / 'doc/git-doc',
    )
  endif
endforeach

if get_option('docs').contains('html')
  configure_file(
    input: 'docinfo-html.in',
    output: 'docinfo.html',
    copy: true,
    install: true,
    install_dir: get_option('datadir') / 'doc/git-doc',
  )

  configure_file(
    input: 'docbook-xsl.css',
    output: 'docbook-xsl.css',
    copy: true,
    install: true,
    install_dir: get_option('datadir') / 'doc/git-doc',
  )

  install_symlink('index.html',
    install_dir: get_option('datadir') / 'doc/git-doc',
    pointing_to: 'git.html',
  )

  xsltproc = find_program('xsltproc')

  user_manual_xml = custom_target(
    command: asciidoc_common_options + [
      '--backend=' + asciidoc_docbook,
      '--doctype=book',
      '--out-file=@OUTPUT@',
      '@INPUT@',
    ],
    input: 'user-manual.txt',
    output: 'user-manual.xml',
    depends: documentation_deps,
  )

  custom_target(
    command: [
      xsltproc,
      '--xinclude',
      '--stringparam', 'html.stylesheet', 'docbook-xsl.css',
      '--param', 'generate.consistent.ids', '1',
      '--output', '@OUTPUT@',
      '@INPUT@',
      user_manual_xml,
    ],
    input: 'docbook.xsl',
    output: 'user-manual.html',
    install: true,
    install_dir: get_option('datadir') / 'doc/git-doc',
  )

  articles = [
    'DecisionMaking.txt',
    'MyFirstContribution.txt',
    'MyFirstObjectWalk.txt',
    'ReviewingGuidelines.txt',
    'SubmittingPatches',
    'ToolsForGit.txt',
    'git-bisect-lk2009.txt',
    'git-tools.txt',
  ]

  foreach article : articles
    custom_target(
      command: asciidoc_common_options + [
        '--backend=' + asciidoc_html,
        '--out-file=@OUTPUT@',
        '@INPUT@',
      ],
      input: article,
      output: fs.stem(article) + '.html',
      depends: documentation_deps,
      install: true,
      install_dir: get_option('datadir') / 'doc/git-doc',
    )
  endforeach

  asciidoc_html_options = asciidoc_common_options + [
    '--backend=' + asciidoc_html,
    '--out-file=@OUTPUT@',
    '--attribute', 'git-relative-html-prefix=../',
    '@INPUT@',
  ]

  subdir('howto')
  subdir('technical')
endif

# Sanity check that we are not missing any tests present in 't/'. This check
# only runs once at configure time and is thus best-effort, only. Furthermore,
# it only verifies man pages for the sake of simplicity.
configured_manpages = manpages.keys() + [ 'git-bisect-lk2009.txt', 'git-tools.txt' ]
actual_manpages = run_command(shell, '-c', 'ls git*.txt scalar.txt',
  check: true,
  env: script_environment,
).stdout().strip().split('\n')

if configured_manpages != actual_manpages
  missing_manpage = [ ]
  foreach actual_manpage : actual_manpages
    if actual_manpage not in configured_manpages
      missing_manpage += actual_manpage
    endif
  endforeach
  if missing_manpage.length() > 0
    error('Man page found, but not configured:\n\n - ' + '\n - '.join(missing_manpage))
  endif

  superfluous_manpage = [ ]
  foreach configured_manpage : configured_manpages
    if configured_manpage not in actual_manpages
      superfluous_manpage += configured_manpage
    endif
  endforeach
  if superfluous_manpage.length() > 0
    error('Man page configured, but not found:\n\n - ' + '\n - '.join(superfluous_manpage))
  endif
endif
